/**
 * 构件一个树形结构
 * 
 * 冬冬公司
 * |-- 总经理
 * |-- 销售部
 *   |-- 销售部总经理
 *   |-- 销售1部
 *     |-- 销售1部业务员1
 * |-- 研发部
 *   |-- 研发1部张三
 *   |-- 研发2部李四
 */

/**
 * @description 抽象构件
 */
interface Component {
  getSelfName(): string
}

/**
 * @description 树枝节点
 */
class Composite implements Component {
  private _name: string = ''
  _compositeList: Set<Component> = new Set()
  constructor(name: string) {
    this._name = name;
  }

  getSelfName(): string {
    return this._name
  }

  add(component: Component): Composite {
    this._compositeList.add(component)
    return this
  }
  remove(component: Component): Composite {
    this._compositeList.delete(component)
    return this
  }
  getChildren(): Set<Component> {
    return this._compositeList
  }
}

/**
 * @description 树叶节点
 */
class Leaf implements Component {
  private _name: string = ''
  constructor(name: string) {
    this._name = name;
  }

  getSelfName(): string {
    return this._name
  }

}

function main() {
  const root = new Composite('冬冬公司')
  const mainManager = new Leaf('公司总经理')
  const departmentSale = new Composite('销售部')
  const departmentDevelopment = new Composite('研发部')
  root.add(mainManager).add(departmentSale).add(departmentDevelopment)

  const managerSale = new Leaf('销售部总经理')
  const departmentSaleChild1 = new Composite('销售1部')
  departmentSale.add(managerSale).add(departmentSaleChild1)

  const salePerson = new Leaf('销售1部业务员')
  departmentSaleChild1.add(salePerson)

  const developmentPerson1 = new Leaf('研发部张三')
  const developmentPerson2 = new Leaf('研发部李四')

  departmentDevelopment.add(developmentPerson1).add(developmentPerson2)

  findChild(root)

}

function findChild(component: Component) {
  if (component instanceof Leaf) {
    console.log(component.getSelfName())
  }
  if (component instanceof Composite) {
    console.log(component.getSelfName());
    component._compositeList.forEach((compositeItem) => {
      findChild(compositeItem)
    })
  }
}
main()